package com.mdhw.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mdhw.common.base.PageData;
import com.mdhw.common.enums.StatusEnum;
import com.mdhw.config.R;
import com.mdhw.system.dao.SysRoleMenuDao;
import com.mdhw.system.entity.*;
import com.mdhw.system.service.*;
import com.mdhw.system.vo.SysMenuTree;
import com.mdhw.system.vo.SysMenuVo;
import com.mdhw.system.vo.SysRoleVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mdhw.system.dao.SysRoleDao;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author Huang
* @date 2022-03-14
*/

@Slf4j
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;

    @Autowired
    private SysUserService sysUserService;



    /**
     * 查询角色列表分页
     * @param pageNo
     * @param pageSize
     * @param name
     * @param code
     * @return
     */
    @Override
    public R<PageData<SysRoleVo>> selectListPage(Long pageNo, Long pageSize, String name, String code) {
        pageNo = pageNo == null ? 1L : pageNo;
        pageSize = pageSize == null ? 20L :pageSize;
        Page page = new Page(pageNo,pageSize);
        QueryWrapper<SysRoleVo> srvQw = new QueryWrapper<>();
        if(StringUtils.isNotBlank(name)){
            srvQw.eq("name",name);
        }
        if(StringUtils.isNotBlank(code)){
            srvQw.eq("code",code);
        }
        srvQw.eq("status",StatusEnum.OK.getCode());
        this.sysRoleDao.selectRoleVoListPage(page,srvQw);
        PageData pageData = PageData.plusPageToPageData(page);
        return R.success(pageData);
    }


    /**
     * 新增角色
     * @param sysRole
     * @return
     */
    @Override
    public R<String> addRole(SysRole sysRole) {
        String code = sysRole.getCode();
        if(code == null || StringUtils.isBlank(code)){
            return R.error("code 不允许为空");
        }
        LambdaQueryWrapper<SysRole> srLqw = new LambdaQueryWrapper<>();
        srLqw.eq(SysRole::getStatus,StatusEnum.OK.getCode());
        srLqw.eq(SysRole::getCode,code);
        List<SysRole> sysRoleList = this.list(srLqw);
        if(sysRoleList != null && sysRoleList.size()>0){
            return R.error("code 不允许重复");
        }
        sysRole.setStatus(StatusEnum.OK.getCode());
        sysRole.setRevision(0);
        if(sysRole.getSortNum() == null){
            sysRole.setSortNum(0);
        }
        boolean isSuccess = this.save(sysRole);
        if(isSuccess){
            return R.success("新增成功");
        }else{
            return R.error("新增失败");
        }
    }

    /**
     * 修改角色
     * @param sysRole
     * @return
     */
    @Override
    public R<String> updateRole(SysRole sysRole) {
        String code = sysRole.getCode();
        if(code == null || StringUtils.isBlank(code)){
            return R.error("code 不允许为空");
        }
        Long id = sysRole.getId();
        LambdaQueryWrapper<SysRole> srLqw = new LambdaQueryWrapper<>();
        srLqw.eq(SysRole::getStatus,StatusEnum.OK.getCode());
        srLqw.eq(SysRole::getCode,code);
        srLqw.ne(SysRole::getId,id);
        List<SysRole> sysRoleList = this.list(srLqw);
        if(sysRoleList != null && sysRoleList.size()>0){
            return R.error("code 不允许重复");
        }
        boolean isSuccess = this.updateById(sysRole);
        if(isSuccess){
            return R.success("修改成功");
        }else{
            return R.error("修改失败");
        }
    }

    /**
     * 删除角色
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public R<String> deleteRole(Long id) {
        SysRole sysRole = this.getById(id);
        sysRole.setStatus(StatusEnum.DELETE.getCode());
        boolean isSuccess = this.updateById(sysRole);

        // 删除 user_role
        if(isSuccess){
            LambdaQueryWrapper<SysUserRole> surLqw = new LambdaQueryWrapper<>();
            surLqw.eq(SysUserRole::getRoleId,id);
            this.sysUserRoleService.remove(surLqw);

            // 删除
            if(isSuccess){
                LambdaQueryWrapper<SysRoleMenu> srmLqw = new LambdaQueryWrapper<>();
                srmLqw.eq(SysRoleMenu::getRoleId,id);
                this.sysRoleMenuService.remove(srmLqw);
            }
        }
        if(isSuccess){
            return R.success("删除成功");
        }else{
            return R.error("删除失败");
        }
    }

    /**
     * 设置角色菜单
     * @param sysRoleVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public R<String> setRoleMenu(SysRoleVo sysRoleVo) {
        //先删除
        Long roleId = sysRoleVo.getId();
        LambdaQueryWrapper<SysRoleMenu> srmLqw = new LambdaQueryWrapper<>();
        srmLqw.eq(SysRoleMenu::getRoleId,roleId);
        this.sysRoleMenuService.remove(srmLqw);

        //List<SysMenuVo> sysMenuVoList = sysRoleVo.getSysMenuVoList();
        List<Long> sysMenuIdList = sysRoleVo.getSysMenuIdList() ;
        /*for(SysMenuVo sysMenuVo:sysMenuVoList){
            sysMenuIdList.add(sysMenuVo.getId());
        }*/
        List<SysRoleMenu> sysRoleMenuList = new ArrayList<>();
        for(Long sysMenuId : sysMenuIdList){
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(sysMenuId);
            sysRoleMenuList.add(sysRoleMenu);
        }
        Boolean isSuccess = this.sysRoleMenuService.saveBatch(sysRoleMenuList);

        if(isSuccess){
            return R.success("设置成功");
        }else{
            return R.error("设置失败");
        }
    }

    /**
     * 查询菜单树通过 RoleId
     * @param id
     * @return
     */
    @Override
    public R<Map<String,Object>> selectMenuTreeByRoleId(Long id) {
        LambdaQueryWrapper<SysMenu> smLqw = new LambdaQueryWrapper<>();
        smLqw.eq(SysMenu::getStatus,StatusEnum.OK.getCode());
        List<SysMenu> sysMenuList = this.sysMenuService.list(smLqw);
        List<Long> sysMenuIdList = this.sysRoleMenuDao.selectMenuIdListByRoleId(id);

        List<SysMenuTree> sysMenuTreeList = this.sysMenuService.selectMenuTree(null, sysMenuIdList);
        Integer size = sysMenuList == null ? 0 : sysMenuList.size();
        Integer checkedSize = sysMenuIdList == null ? 0 : sysMenuIdList.size();
        Map<String,Object> returnData = new HashMap<>();
        returnData.put("treeList",sysMenuTreeList);
        returnData.put("treeSize",size);
        returnData.put("checkedSize",checkedSize);
        return R.success(returnData);
    }


    @Override
    public R<List<SysRole>> selectAllList(String name,String type) {
        SysUser sysUser = sysUserService.getUserVoByToken();
        boolean isSystemAdmin = sysUserService.isSystemAdmin(sysUser.getId());
        LambdaQueryWrapper<SysRole> srLqw = new LambdaQueryWrapper<>();
        //超级管理员查询所有
        if(!isSystemAdmin){
            srLqw.eq(SysRole::getCode,type);
        }
        srLqw.eq(SysRole::getStatus,StatusEnum.OK.getCode());
        if(name != null){
            srLqw.like(SysRole::getName,name);
        }
        List<SysRole> sysRoleList = this.list(srLqw);
        return R.success(sysRoleList);
    }


    @Override
    public R<SysRoleVo> selectSysRoleVoByUserId(Long userId) {
        return null;
    }

    /**
     * 是否能审核
     * @param userId
     * @return
     */
    @Override
    public Boolean isCanShenheZxTopUp(Long userId){
        LambdaQueryWrapper<SysUserRole> surLqw=  new LambdaQueryWrapper<>();
        surLqw.eq(SysUserRole::getUserId,userId);
        List<SysUserRole> sysUserRoleList = this.sysUserRoleService.list(surLqw);
        if(sysUserRoleList == null || sysUserRoleList.size() == 0){
            return Boolean.FALSE;
        }
        List<Long> roleIdList  = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());

        LambdaQueryWrapper<SysRole> srLqw = new LambdaQueryWrapper<>();
        srLqw.in(SysRole::getId,roleIdList);
        List<SysRole> sysRoleList = this.list(srLqw);
        if(sysRoleList == null || sysRoleList.size() == 0){
            return Boolean.FALSE;
        }
        for(SysRole sysRole : sysRoleList){
            String code = sysRole.getCode();
            if("admin".equals(code) || "caiwu".equals(code)){
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }
}
